package com.boy.rpc.framework.console.controller;

import com.boy.rpc.framework.console.Constant;
import com.boy.rpc.framework.console.appenum.QueryEnum;
import com.boy.rpc.framework.console.bean.Pagination;
import com.boy.rpc.framework.console.bean.RKey;
import com.boy.rpc.framework.console.service.IRedisService;
import com.boy.rpc.framework.console.service.ViewService;
import com.boy.rpc.framework.console.utils.ConvertUtil;
import com.boy.rpc.framework.console.utils.InitKeysCacheUtil;
import com.boy.rpc.framework.console.utils.PaginationUtils;
import com.boy.rpc.framework.console.utils.StringUtil;
import com.boy.rpc.framework.console.utils.ztree.ZNode;
import com.boy.rpc.framework.console.workbench.WorkbenchResult;
import com.boy.rpc.framework.console.workbench.response.WorkbenchResponseBodyJson;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Created by wesley on 2017-03-16.
 */
@Controller
@RequestMapping("/redis")
public class RedisController {

    private static final Logger logger = LoggerFactory.getLogger(RedisController.class);

    @Autowired
    private ViewService viewService;
    @Autowired
    private IRedisService redisService;

    @RequestMapping(method= RequestMethod.GET)
    public Object home(HttpServletRequest request, HttpServletResponse response) {
        logger.debug("view index");
        String defaultServerName = (String) (Constant.redisServerCache.get(0)==null?"":Constant.redisServerCache.get(0).get("name"));
        request.setAttribute("serverName", defaultServerName);
        request.setAttribute("dbIndex", Constant.DEFAULT_DBINDEX);
        return "redirect:/redis/stringList/"+defaultServerName + "/" +Constant.DEFAULT_DBINDEX;
    }

    /**
     * 当前服务器的keys列表
     * @param request
     * @param response
     * @param serverName
     * @param dbIndex
     * @return
     */
    @RequestMapping(value="/stringList/{serverName}/{dbIndex}", method=RequestMethod.GET)
    public Object stringList(HttpServletRequest request, HttpServletResponse response,
                             @PathVariable String serverName, @PathVariable String dbIndex) {
        logger.debug("get list servers");

        refreshByMode();

        String queryKey = StringUtil.getParameterByDefault(request, "queryKey", Constant.MIDDLE_KEY);
        String queryKey_ch = QueryEnum.valueOf(queryKey).getQueryKeyCh();
        String queryValue = StringUtil.getParameterByDefault(request, "queryValue", Constant.EMPTY_STRING);
        String queryByKeyPrefixs = StringUtil.getParameterByDefault(request, "queryByKeyPrefixs", Constant.EMPTY_STRING);

        String[] keyPrefixs = request.getParameterValues("keyPrefixs");

        Pagination pagination = PaginationUtils.stringListPagination(request, queryKey, queryKey_ch, queryValue, queryByKeyPrefixs);

        InitKeysCacheUtil.logCurrentTime("viewService.getRedisKeys start");
        Set<RKey> redisKeys = viewService.getRedisKeys(pagination, serverName, dbIndex, keyPrefixs, queryKey, queryValue);
        InitKeysCacheUtil.logCurrentTime("viewService.getRedisKeys end");
        request.setAttribute("redisServers", Constant.redisServerCache);
        request.setAttribute("basePath", Constant.BASE_PATH);
        request.setAttribute("queryLabel_ch", queryKey_ch);
        request.setAttribute("queryLabel_en", queryKey);
        request.setAttribute("queryValue", queryValue);
        request.setAttribute("serverName", serverName);
        request.setAttribute("dbIndex", dbIndex);
        request.setAttribute("redisKeys", redisKeys);
        request.setAttribute("refreshMode", Constant.refreshMode.getLabel());
        request.setAttribute("change2ShowType", Constant.showType.getChange2());
        request.setAttribute("showType", Constant.showType.getState());
        request.setAttribute("pagination", pagination.createLinkTo());
        request.setAttribute("viewPage", "redis/list.jsp");
        return "admin/main";
    }

    /**
     * 是否显示类型
     * @param request
     * @param response
     * @param state
     * @return
     */
    @RequestMapping(value="/changeShowType", method=RequestMethod.POST)
    @ResponseBody
    public Object changeShowType(HttpServletRequest request, HttpServletResponse response,
                                 @RequestParam String state) {
        logger.debug("changeShowType operations");
        viewService.changeShowType(state);
        return WorkbenchResponseBodyJson.custom().build();
    }

    /**
     * 获取左侧服务器树
     * @param request
     * @param response
     * @return
     */
    @RequestMapping(value="/serverTree", method=RequestMethod.GET)
    @ResponseBody
    public Object serverTree(HttpServletRequest request, HttpServletResponse response) {
        logger.debug("get serverTree");
        Set<ZNode> keysSet = viewService.getLeftTree();
        return keysSet;
    }

    /**
     * 刷新
     * @param request
     * @param response
     * @param mode
     * @return
     */
    @RequestMapping(value="/refreshMode", method=RequestMethod.POST)
    @ResponseBody
    public Object refreshMode(HttpServletRequest request, HttpServletResponse response,
                              @RequestParam String mode) {
        logger.debug("refresh redis server Mode");
        viewService.changeRefreshMode(mode);
        return WorkbenchResponseBodyJson.custom().build();
    }

    /**
     * 获取key-value
     * @param request
     * @param response
     * @param serverName
     * @param dbIndex
     * @param dataType
     * @param key
     * @return
     */
    @RequestMapping(value="/KV", method=RequestMethod.GET)
    @ResponseBody
    public Object getKV(HttpServletRequest request, HttpServletResponse response,
                        @RequestParam String serverName, @RequestParam int dbIndex,
                        @RequestParam String dataType,
                        @RequestParam String key) {
        logger.debug("----redisController getKv----");

        WorkbenchResult result = (WorkbenchResult)redisService.getKV(serverName, dbIndex, dataType, key);
        logger.debug("----redisController getKv----result:{}"+request);
        return WorkbenchResponseBodyJson.custom().setAll(result, Constant.GET_KV).build();
    }

    /**
     * 添加key-value
     * @param request
     * @param response
     * @param serverName
     * @param dbIndex
     * @param dataType
     * @param key
     * @return
     */
    @RequestMapping(value="/KV", method=RequestMethod.POST)
    @ResponseBody
    public Object updateKV(HttpServletRequest request, HttpServletResponse response,
                           @RequestParam String serverName, @RequestParam int dbIndex,
                           @RequestParam String dataType,
                           @RequestParam String key) {
        logger.debug("----redisController addKv----");

        String[] value = request.getParameterValues("value");
        double[] score = ConvertUtil.convert2Double(request.getParameterValues("score"));
        String[] member = request.getParameterValues("member");
        String[] field = request.getParameterValues("field");
        logger.debug("----redisController addKv----key:"+key+",value:"+value);
        redisService.addKV(serverName, dbIndex, dataType, key, value, score, member, field);

        return WorkbenchResponseBodyJson.custom().build();
    }

    private void refreshByMode() {
        logger.debug("refreshByMode start!");
        switch(Constant.refreshMode) {
            case manually:
                break;
            case auto:
                viewService.refresh();
                break;
        }
    }

    /**
     * 删除key-value
     * @param request
     * @param response
     * @param serverName
     * @param dbIndex
     * @param deleteKeys
     * @return
     */
    @RequestMapping(value="/delKV", method=RequestMethod.POST)
    @ResponseBody
    public Object delKV(HttpServletRequest request, HttpServletResponse response,
                        @RequestParam String serverName, @RequestParam int dbIndex,
                        @RequestParam String deleteKeys) {

        redisService.delKV(serverName, dbIndex, deleteKeys);

        return WorkbenchResponseBodyJson.custom().build();

    }

    /**
     * 添加redis服务
     * @param request
     * @param response
     * @param host
     * @param name
     * @param port
     * @param password
     * @return
     */
    @RequestMapping(value="/addServer", method=RequestMethod.POST)
    @ResponseBody
    public Object addServer(HttpServletRequest request, HttpServletResponse response,
                            @RequestParam String host,
                            @RequestParam String name,
                            @RequestParam int port,
                            @RequestParam String password) {

        redisService.addRedisServer(name, host, port, password);

        return WorkbenchResponseBodyJson.custom().build();
    }

    /**
     * 删除值
     * @param request
     * @param response
     * @param serverName
     * @param dbIndex
     * @param key
     * @param dataType
     * @return
     */
    @RequestMapping(value="/delValue", method=RequestMethod.POST)
    @ResponseBody
    public Object delValue(HttpServletRequest request, HttpServletResponse response,
                           @RequestParam String serverName,
                           @RequestParam int dbIndex,
                           @RequestParam String key,
                           @RequestParam String dataType) {

        redisService.delValue(serverName, dbIndex, key);

        return WorkbenchResponseBodyJson.custom().build();
    }

    /**
     * 更新值
     * @param request
     * @param response
     * @param serverName
     * @param dbIndex
     * @param key
     * @param dataType
     * @param value
     * @return
     */
    @RequestMapping(value="/updateValue", method=RequestMethod.POST)
    @ResponseBody
    public Object updateValue(HttpServletRequest request, HttpServletResponse response,
                              @RequestParam String serverName,
                              @RequestParam int dbIndex,
                              @RequestParam String key,
                              @RequestParam String dataType,
                              @RequestParam String value) {

        redisService.updateValue(serverName, dbIndex, key, value);

        return WorkbenchResponseBodyJson.custom().build();
    }
}
